﻿using System;
using System.Collections.Generic;
using System.Linq;
namespace IFramework
{
    public static partial class ListExtension
    {
        public static List<T> ForEachReverse<T>(this List<T> selfList, Action<T> action)
        {
            if (action == null) throw new ArgumentException();

            for (var i = selfList.Count - 1; i >= 0; --i)
                action(selfList[i]);
            return selfList;
        }
        public static void ForEach<T>(this List<T> list, Action<int, T> action)
        {
            for (var i = 0; i < list.Count; i++)
            {
                action(i, list[i]);
            }
        }
        public static void CopyTo<T>(this List<T> from, List<T> to, int begin = 0, int end = -1)
        {
            if (begin < 0)
            {
                begin = 0;
            }
            var endIndex = Math.Min(from.Count, to.Count) - 1;
            if (end != -1 && end < endIndex)
            {
                endIndex = end;
            }
            for (var i = begin; i < end; i++)
            {
                to[i] = from[i];
            }
        }
        public static T[] ToArraySavely<T>(this List<T> selfList)
        {
            var res = new T[selfList.Count];
            for (var i = 0; i < selfList.Count; i++)
            {
                res[i] = selfList[i];
            }
            return res;
        }
        public static T TryGet<T>(this List<T> selfList, int index)
        {
            return selfList.Count > index ? selfList[index] : default(T);
        }

        //0,1,3,4=>2
        public static int GetEmptyInt(this List<int> list, int minVal = 0)
        {
            list.Sort();
            list = list.Distinct().ToList();
            switch (list.Count)
            {
                case 0: return minVal;
                case 1: return list[0] == minVal ? minVal + 1 : minVal;
                default:
                    int tempIndex = 0;
                    if (isExistEmptyIndex(list, 0, list.Count - 1, ref tempIndex))
                    {
                        return tempIndex;
                    }
                    return list[0] > minVal ? minVal : list[list.Count - 1] + 1;
            }
        }
        private static bool isExistEmptyIndex(List<int> list, int startIndex, int endIndex, ref int index)
        {
            if (Math.Abs(list[startIndex] - list[endIndex]) == endIndex - startIndex) return false;
            if (endIndex - startIndex == 1)
            {
                index = list[startIndex] + 1;
                return true;
            }
            int midIndex = (endIndex - startIndex) / 2 + startIndex;
            //   if (midIndex < startIndex || midIndex > endIndex) return false;
            return isExistEmptyIndex(list, startIndex, midIndex, ref index) ||
                isExistEmptyIndex(list, midIndex, endIndex, ref index);
        }
    }
}